主从复制
1.这种架构有如下的好处:
<1> 数据备份。
<2> 数据恢复。
<3> 读写分离。3>2>1>
2.下面我们就一一实践
实际应用中我们肯定是多服务器部署,限于自己懒的装虚拟机,就在一台机器上实践了。
第一步:我们把mongodb文件夹放在D盘和E盘,模拟放在多服务器上。
第二步:启动D盘上的mongodb,把该数据库指定为主数据库,其实命令很简单:
端口还是默认的27017.
开启主服务器:
第三步:同样的方式启动E盘上的mongodb,指定该数据库为从属数据库,命令也很简单,当然我们要换一个端口,比如:8888。
source 表示主数据库的地址。
|
|
开启从服务器:
报错了:
这是由于之前误操作,127.0.0.1:2222 != 17.0.0.1:27017,IP地址错了。可以删掉D:\Projects\mongodb2\db的db文件夹新建。尝试修改主服务器的端口。
一般还可能有下面两个错误:
(1)D:\Projects\mongodb2\db的db文件夹不存在导致的错误;创建该文件夹即可。
(2)D:\Projects\mongodb2\db下存在mongod.lock文件。删掉即可。
重新来:
开主服务器:
提示:
成功。
开启从服务器:
提示:
成功。从中我们发现了一条:“applied 1 operations”这样的语句,并且发生的时间相隔10s,也就说明从属数据库每10s就向主数据库同步数据,同步依据也就是寻找主数据库的”OpLog“日志,可以在图中红色区域内发现”sync_pullOpLog“字样。
接下来,我们可以打开客户端,连接从服务器进行测试了。再打开一个命令行窗口:
好家伙,数据全都有了!数据已经同步更新成功!
3.如果我还想增加一台从属数据库,但是我不想在启动时就指定,而是后期指定,那么mongodb可否做的到呢?答案肯定是可以的。我们的主或者从属数据库中都有一个叫做local的集合,主要是用于存放内部复制信息。
主服务器不用关,我们可以再新增一台或者关掉从服务器,重新开启从服务器:
看上面的log,提示没有主数据库,没关系,某一天我们良心发现,给他后期补贴一下,哈哈,再开一个cmd窗口,打开客户端,语句也就是在sources中add一个host地址:
|
|
使用local集合
从主服务器127.0.0.1:2222复制数据
使用test集合
最后发现数据也同步到127.0.0.1:3333这台后期同步的从属数据库中….
客户端插入一条数据试试:
切换连接到主服务器就可以新增了:
再连接到从服务器发现数据也同步了,即不用重新去追加数据。
4.读写分离
这种手段在大一点的架构中都有实现,在mongodb中其实很简单,在默认的情况下,从属数据库不支持数据的读取,但是没关系,在驱动中给我们提供了一个叫做“slaveOkay”(?)来让我们可以显示的读取从属数据库来减轻主数据库的性能压力。
主从复制的选项
–only 在从节点上指定只复制特定的某个数据库(默认是复制所有数据库)
–slavedelay 用在从节点上,当应用主节点的操作时,从节点增加延时复制(单位秒).这样就能轻松设置延时从节点,这种节点对用户
无意中删除重要文档或者插入垃圾数据等有防护作用,这些不良操作都会被复制到所有的从节点上,通过延时执行操作,
可以有个恢复的时间差.
–fastsync 以主节点的数据快照为基础启动从节点.如果数据目录一开始是主节点的数据快照,从节点用这个选项启动要比
做完整的同步快的多.
–autoresync 如果从节点与主节点不同步了,则自动重新同步
–oplogsize 主节点oplog的大小(单位MB)
副本集
这个也是很牛X的主从集群,不过跟上面的集群还是有两点区别的。
<1>该集群没有特定的主数据库。1>
<2>如果哪个主数据库宕机了,集群中就会推选出一个从属数据库作为主数据库顶上,这就具备了自动故障恢复功能。2>
好,我们现在就来试一下,首先把所有的cmd窗口关掉重新来,清掉db下的所有文件(不清除后续操作可能会报错)。
第一步: 既然我们要建立集群,就得取个集群名字,这里就取名shopex, –replSet表示让服务器知道shopex下还有其他数据库,
这里就把D盘里面的mongodb程序打开,端口为2222。指定端口为3333是shopex集群下的另一个数据库服务器。
|
|
第二步: 既然上面说3333是另一个数据库服务器,不要急,现在就来开,这里把另外一个目录mongodb2的mongodb程序打开。
|
|
第三步: ok,看看上面的日志,似乎我们还没有做完,是的,log信息告诉我们要初始化一下“副本集“,既然日志这么说,那我也就这么做,随便连接一下哪个服务器都行,不过一定要进入admin集合。
|
|
第一次设置报告了一个错误:
“errmsg” : “‘127.0.0.1:3333’ has data already, cannot initiate set.”
原因是我没有清除D:\Projects\mongodb2\下的db。关闭D:\Projects\mongodb2\服务器并删除db下的文件后重新打开mongodb2服务器,并再次设置初始化:显示ok。
第四步: 开启成功后,我们要看看谁才能成为主数据库服务器,可以看到端口为2222的已经成为主数据库服务器。
第五步:我们知道sql server里面有一个叫做仲裁服务器,那么mongodb中也是有的,跟sql server一样,仲裁只参与投票选举,这里我们把mongodb3的mongodb作为仲裁服务器,然后指定shopex集群中的任一个服务器端口,这里就指定2222。
|
|
然后我们在admin集合中使用rs.addArb()追加即可。
追加好了之后,我们使用rs.status()来查看下集群中的服务器状态,图中我们可以清楚的看到谁是主,还是从,还是仲裁。
|
|
上面的结果显示很清楚。
不是说该集群有自动故障恢复吗?那么我们就可以来试一下,在2222端口的cmd服务器按Ctrl+C来KO掉该服务器,立马我们发现在3333端口的从属服务器即可顶上,最后大家也可以再次使用rs.status()来看下集群中服务器的状态。
其它:
在从服务器是无法查看数据:
切换到主服务器就可以了
当然也可以使用下rs.slaveOk() 命令,使其可以查询数据(还是不能更新之类的)
拓展:
rs相关命令
后记:
有些问题,关掉2222端口的服务器,3333和4444都提示:
couldn’t connect to server 127.0.0.1:2222(127.0.0.1)
然后再打开2222端口的服务器,现在3333的变成主服务器了。
再关掉3333提示, couldn’t connect to server 127.0.0.1:3333 (127.0.0.1),且使用rs.status()显示3333的状态是 “stateStr” : “(not reachable/healthy)”
参考:
8天学通MongoDB——第五天 主从复制 - 一线码农 - 博客园
http://www.cnblogs.com/huangxincheng/archive/2012/03/04/2379755.html